package com.wan37.logic.listener;

import com.wan37.logic.listener.event.BaseGameEvent;
import com.wan37.logic.listener.event.EventType;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author : luoyong
 * @date : 2020-06-29 10:26
 **/
public class EventDispatcher {
    private final static EventDispatcher instance = new EventDispatcher();

    private EventDispatcher() {
    }

    public static EventDispatcher getInstance() {
        return instance;
    }

    /**
     * 事件类型与事件监听器列表的映射关系
     */
    private final Map<EventType, Set<Object>> observers = new HashMap<>();

    /**
     * 注册事件监听器
     *
     * @param eventType
     * @param listener
     */
    public void registerEvent(EventType eventType, Object listener) {
        Set<Object> listeners = observers.get(eventType);
        if (listeners == null) {
            listeners = new CopyOnWriteArraySet<>();
            observers.put(eventType, listeners);
        }
        listeners.add(listener);
    }

    /**
     * 分发事件
     *
     * @param event
     */
    public void fireEvent(BaseGameEvent event) {
        if (event == null) {
            throw new NullPointerException("event cannot be null");
        }
        if (event.isSynchronized()) {
            triggerEvent(event);
        }
    }

    private void triggerEvent(BaseGameEvent event) {
        EventType eventType = event.getEventType();
        Set<Object> listeners = observers.get(eventType);
        if (listeners != null) {
            listeners.forEach(listener -> {
                try {
                    ListenerManager.getInstance().fireEvent(listener, event);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }
}
